// 第一步，创建结构体，表示错误类型，描述错误详情
#[derive(Debug)]
struct MyError {
    detail: String,
}

// 第二步，实现std::fmt::Display特质，实现打印方法
impl std::fmt::Display for MyError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "MyError: {}", self.detail)
    }
}

// 第三步，实现std::error::Error特质，实现基础机制（包括不限于，错误传递）
impl std::error::Error for MyError {
    fn description(&self) -> &str {
        // 这里&String自动转换成&str
        &self.detail
    }
}

fn do_something() -> Result<(), MyError> {
    // 这里实现一些操作，可能会返回错误
    // 如果返回错误，使用MyError来封装错误信息
    Err(MyError {
        detail: String::from("Something went wrong"),
    })
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 使用match匹配模式
    match do_something() {
        Ok(_) => println!("Everything went well"),
        Err(err) => println!("Error: {}", err),
    }

    // 或者使用?操作符简化代码
    do_something()?;
    Ok(())
}
